package com.ybw.order.demo.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.binarywang.wxpay.bean.request.WxPayDownloadBillRequest;
import com.github.binarywang.wxpay.bean.request.WxPayOrderQueryRequest;
import com.github.binarywang.wxpay.bean.result.WxPayBillInfo;
import com.github.binarywang.wxpay.bean.result.WxPayBillResult;
import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.ybw.order.demo.constant.IsDelDbConstant;
import com.ybw.order.demo.config.wx.WxPayConfiguration;
import com.ybw.order.demo.constant.OrderConstant;
import com.ybw.order.demo.constant.ReturnCode;
import com.ybw.order.demo.constant.db.GoodsInfoDbConstant;
import com.ybw.order.demo.constant.db.OrderInfoDBConstant;
import com.ybw.order.demo.constant.db.OrderReconciliationMistakeDBConstant;
import com.ybw.order.demo.constant.mq.MqConstant;
import com.ybw.order.demo.dto.HandleStockStatusDTO;
import com.ybw.order.demo.entity.GoodsInfo;
import com.ybw.order.demo.entity.OrderInfo;
import com.ybw.order.demo.entity.OrderReconciliationMistake;
import com.ybw.order.demo.exception.BizException;
import com.ybw.order.demo.mapper.GoodsInfoMapper;
import com.ybw.order.demo.mapper.OrderInfoMapper;
import com.ybw.order.demo.service.*;
import com.ybw.order.demo.utils.DateTimeUtils;
import com.ybw.order.demo.utils.GsonUtils;
import com.ybw.order.demo.utils.MyStringUtils;
import com.ybw.order.demo.vo.order.req.CancelOrderVO;
import com.ybw.order.demo.vo.order.req.CreateOrderReqVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.MessageConst;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单 服务实现类
 * </p>
 *
 * @author ybwei
 * @since 2022-02-20
 */
@Service
@Slf4j
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {
    @Resource
    private GoodsInfoService goodsService;
    @Resource
    private GoodsInfoMapper goodsInfoMapper;
    @Resource
    private RocketMQTemplate rocketMQTemplate;
    @Resource
    private SnowFlakeService snowFlakeService;
    @Resource(name = "taskExecutor")
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
    @Resource
    private SenderService senderService;
    @Resource
    private WxPayConfiguration wxPayConfiguration;
    @Resource
    private OrderInfoMapper orderInfoMapper;
    @Resource
    private OrderReconciliationMistakeService orderReconciliationMistakeService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createOrder2(CreateOrderReqVO createOrderReqVO) {
        //1、获取商品信息
        GoodsInfo goods = goodsService.getGoodsInfo(createOrderReqVO.getGoodsInfoId());
        log.info("剩余库存：{}", goods.getStockCount());
        //1.1 校验
        if (goods == null || goods.getIsAllowSale() == 0 || goods.getStockCount().intValue() < createOrderReqVO.getBuyCount().intValue()) {
            log.info("check fail");
            throw new BizException(ReturnCode.ERROR);
        }
        //2、减库存
        goodsService.handleStockStatusInRedis(goods.getId(), HandleStockStatusDTO.Handle.MINUS);
        //3、创建订单
        saveOrderInfo(createOrderReqVO, goods);
        //4、发送消息
        asyncDelaySend(createOrderReqVO.getOrderNo());
        log.info("success");
    }

    /**
     * mq延迟队列
     *
     * @param orderNo
     * @methodName: asyncDelaySend
     * @return: void
     * @author: geoffrey
     * @date: 2022/2/20
     **/
    public void asyncDelaySend(String orderNo) {
        //messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
        //4 指的是30s
        Message<String> message = MessageBuilder.withPayload(orderNo)
                .setHeader(MessageConst.PROPERTY_KEYS, MyStringUtils.generateUUID())
                .setHeader(MessageConst.PROPERTY_PRODUCER_GROUP, MqConstant.PRODUCER_GROUP)
                .build();
        rocketMQTemplate.asyncSend(MqConstant.TOPIC, message, new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {
                log.info("asyncDelaySend:{}", JSON.toJSONString(sendResult));
            }

            @Override
            public void onException(Throwable e) {
                log.error("消息发送失败,消息体:{}", JSON.toJSONString(message), e);
            }

        }, 2000, 5);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelOrder(CancelOrderVO cancelOrderVO) {
        OrderInfo orderInfo = this.lambdaQuery()
                .eq(OrderInfo::getOrderNo, cancelOrderVO.getOrderNo())
                .one();
        if (orderInfo == null || orderInfo.getStatus() != 0) {
            //为空 或 状态！=待支付
            log.info("为空 或 状态！=待支付");
            return;
        }
        //2、修改库存
        goodsInfoMapper.updateStockCount(orderInfo.getGoodsId(), orderInfo.getBuyCount());
        GoodsInfo goods = goodsService.getById(orderInfo.getGoodsId());
        if (goods == null) {
            return;
        }
        if (goods.getStockCount() > goods.getTotalStockCount()) {
            throw new BizException(ReturnCode.GOODS_INFO_EXCEED);
        }
        //3、修改订单状态
        this.lambdaUpdate()
                .set(OrderInfo::getStatus, 2)
                .eq(OrderInfo::getId, orderInfo.getId())
                .update();
    }

    @Override
    public void notifyOrder(String orderNo) {
        this.lambdaUpdate()
                .eq(OrderInfo::getOrderNo, orderNo)
                .eq(OrderInfo::getStatus, 0)
                .set(OrderInfo::getStatus, 1)
                .update();
    }

    @Override
    public String generateOrderNo() {
        return new StringBuilder()
                .append(getOrderNoPre())
                .append(snowFlakeService.nextId())
                .toString();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createOrder(CreateOrderReqVO createOrderReqVO) {
        //1、获取商品信息
        GoodsInfo goodsInfo = goodsService.getGoodsInfo(createOrderReqVO.getGoodsInfoId());
        log.info("剩余库存：{}", goodsInfo.getStockCount());
        //1.1 校验库存
        if (goodsInfo == null || goodsInfo.getStockCount().intValue() < createOrderReqVO.getBuyCount().intValue()) {
            log.info("check fail");
            throw new BizException(ReturnCode.ERROR);
        }
        //1.2 发售时间
        if (LocalDateTime.now().isBefore(goodsInfo.getStartSaleTime()) || GoodsInfoDbConstant.AllowSale.OFF_SHELF.getCode().equals(goodsInfo.getIsAllowSale())) {
            //1.4 发售时间未到或发售结束时间已过或未上架
            log.info("订单号：{}，{}", createOrderReqVO.getOrderNo(), ReturnCode.GOODS_INFO_SALE_NOT_TIME_ERROR.getMsg());
            throw new BizException(ReturnCode.GOODS_INFO_SALE_NOT_TIME_ERROR);
        }
        //2、减库存
        goodsService.handleStockStatusInRedis(goodsInfo.getId(), HandleStockStatusDTO.Handle.MINUS);
        //3、创建订单
        saveOrderInfo(createOrderReqVO, goodsInfo);
        //4、TODO 微信支付-超时未支付取消订单
//        asyncDelaySend(createOrderReqVO.getOrderNo());
        //5、发送mq
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
            @Override
            public void afterCommit() {
                threadPoolTaskExecutor.execute(() -> {
                    //1、减库存
                    senderService.sendOrderHandleStockStatus(new HandleStockStatusDTO(createOrderReqVO.getGoodsInfoId(), HandleStockStatusDTO.Handle.MINUS));
                });
            }
        });
    }


    /**
     * 创建订单
     *
     * @param createOrderReqVO
     * @param goodsInfo
     * @methodName: saveOrderInfo
     * @return: void
     * @author: ybw
     * @date: 2022/9/2
     **/
    private void saveOrderInfo(CreateOrderReqVO createOrderReqVO, GoodsInfo goodsInfo) {
        OrderInfo order = new OrderInfo();
        order.setOrderNo(createOrderReqVO.getOrderNo());
        order.setGoodsId(createOrderReqVO.getGoodsInfoId());
        order.setBuyCount(createOrderReqVO.getBuyCount());
        order.setSalePrice(goodsInfo.getSalePrice());
        order.setPayPrice(goodsInfo.getSalePrice());
        order.setStatus(OrderInfoDBConstant.Status.WAIT_PAY.getCode());
        save(order);
    }

    /**
     * 获取订单前缀
     *
     * @author: ybw
     * @date: 2022/7/27
     **/
    private String getOrderNoPre() {
        return new StringBuilder()
                .append(OrderConstant.OrderNoPre.RESERVE)
                .append(OrderConstant.OrderNoPre.SUPERMARKET)
                .toString();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void reconciliation() throws Exception {
        //1、获取昨日微信账单
        LocalDateTime yesterdayTime = LocalDateTime.now().minusDays(1);
        List<WxPayBillInfo> wxBillInfoList = getYesterdaySuccessBillInfoList(yesterdayTime);
        //2、获取昨日数据库账单
        List<OrderInfo> orderInfoList = getYesterdaySuccessOrderInfo(yesterdayTime);
        if (CollectionUtils.isEmpty(wxBillInfoList) && CollectionUtils.isEmpty(orderInfoList)) {
            //昨日微信账单和数据库账单都为空
            return;
        }
        //3、订单是否存在需要处理的订单
        //3.1 获取微信订单差集
        List<OrderReconciliationMistake> moreWxPayBillInfoList = compareWxBillInfoListAndOrderInfo(wxBillInfoList, orderInfoList);
        saveOrderReconciliationMistakeList(moreWxPayBillInfoList);
        //3.2 获取数据库订单差集
        List<OrderReconciliationMistake> diffOrderInfoList = compareOrderInfoAndWxBillInfoList(wxBillInfoList, orderInfoList);
        saveOrderReconciliationMistakeList(diffOrderInfoList);
    }

    /**
     * 获取数据库订单差集
     * 数据库订单差集=昨日数据库账单-昨日微信账单
     *
     * @param wxBillInfoList
     * @param orderInfoList
     * @methodName: compareOrderInfoAndWxBillInfoList
     * @return: java.util.List<com.zt.ztsc.server.modules.order.entity.OrderInfo>
     * @author: ybw
     * @date: 2022/4/8
     **/
    private List<OrderReconciliationMistake> compareOrderInfoAndWxBillInfoList(List<WxPayBillInfo> wxBillInfoList, List<OrderInfo> orderInfoList) {
        if (CollectionUtils.isEmpty(orderInfoList)) {
            //1、昨日数据库账单为空
            return new ArrayList<>();
        }
        if (CollectionUtils.isEmpty(wxBillInfoList)) {
            //2、昨日微信账单为空
            return buildLocalOrderReconciliationMistakeList(orderInfoList,OrderReconciliationMistakeDBConstant.Type.LOST_LIST);
        }
        //3、数据库订单差集=昨日数据库账单-昨日微信账单
        List<OrderInfo> diffOrderInfoList = orderInfoList.stream().filter(orderInfo -> {
            return !wxBillInfoList.stream().anyMatch(wxPayBillInfo ->{
                //订单号相同且金额相同
                return orderInfo.getOrderNo().equals(wxPayBillInfo.getOutTradeNo()) && orderInfo.getPayPrice().equals(new BigDecimal(wxPayBillInfo.getTotalFee()));
            });
        }).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(diffOrderInfoList)) {
            return new ArrayList<>();
        }
        //4、获取差异数据库订单
        return diffOrderInfoList.stream().map(orderInfo -> {
            WxPayOrderQueryRequest wxPayOrderQueryRequest=new WxPayOrderQueryRequest();
            wxPayOrderQueryRequest.setOutTradeNo(orderInfo.getOrderNo());
            try {
                //4.1 获取微信订单信息
                WxPayOrderQueryResult wxPayOrderQueryResult=wxPayConfiguration.getMaService(wxPayConfiguration.getDefaultAppid()).queryOrder(wxPayOrderQueryRequest);
                if(WxPayConstants.WxpayTradeStatus.SUCCESS.equals(wxPayOrderQueryResult.getTradeState())){
                    //微信返回的总金额，单位为分;订单金额，单位为元;
                    if(orderInfo.getPayPrice().multiply(new BigDecimal(100)).compareTo(new BigDecimal(wxPayOrderQueryResult.getTotalFee()))==0){
                        //4.2 订单号相同，且金额相同
                        return null;
                    }
                    //4.3 订单号相同，且金额不一致
                    return buildLocalOrderReconciliationMistake(orderInfo,OrderReconciliationMistakeDBConstant.Type.MONEY_DIFFER);
                }
            } catch (WxPayException e) {
                //4.4 微信订单不存在或其他报错情况
                log.error("compareOrderInfoAndWxBillInfoList error:",e);
            }
            //4.5 其他情况
            return buildLocalOrderReconciliationMistake(orderInfo,OrderReconciliationMistakeDBConstant.Type.LOST_LIST);
        }).collect(Collectors.toList());
    }

    /**
     *
     * @methodName: buildLocalOrderReconciliationMistakeList
     * @param orderInfoList
     * @param type
     * @return: java.util.List<com.zt.ztsc.server.modules.order.entity.OrderReconciliationMistake>
     * @author: ybw
     * @date: 2022/4/19
     **/
    private List<OrderReconciliationMistake> buildLocalOrderReconciliationMistakeList(List<OrderInfo> orderInfoList, OrderReconciliationMistakeDBConstant.Type type) {
        if (CollectionUtils.isEmpty(orderInfoList)) {
            return new ArrayList<>();
        }
        return orderInfoList.stream().map(orderInfo ->
                buildLocalOrderReconciliationMistake(orderInfo, type)
        ).collect(Collectors.toList());
    }

    /**
     *
     * @methodName: buildLocalOrderReconciliationMistake
     * @param type
     * @param orderInfo
     * @return: com.zt.ztsc.server.modules.order.entity.OrderReconciliationMistake
     * @author: ybw
     * @date: 2022/4/19
     **/
    private OrderReconciliationMistake buildLocalOrderReconciliationMistake(OrderInfo orderInfo,OrderReconciliationMistakeDBConstant.Type type) {
        OrderReconciliationMistake orderReconciliationMistake=new OrderReconciliationMistake();
        orderReconciliationMistake.setType(type.getCode());
        orderReconciliationMistake.setOrderId(orderInfo.getId());
        orderReconciliationMistake.setOrdNo(orderInfo.getOrderNo());
        orderReconciliationMistake.setOrdStatus(orderInfo.getStatus());
        orderReconciliationMistake.setOrdTotalMoneyPaid(orderInfo.getPayPrice());
        return orderReconciliationMistake;
    }

    /**
     * 保存微信差订单异记录
     * @methodName: saveOrderReconciliationMistakeList
     * @param orderReconciliationMistakeList
     * @return: void
     * @author: ybw
     * @date: 2022/4/8
     **/
    private void saveOrderReconciliationMistakeList(List<OrderReconciliationMistake> orderReconciliationMistakeList) {
        if (CollectionUtils.isEmpty(orderReconciliationMistakeList)) {
            return;
        }
        //1、获取订单号
        List<String> ordNoList = orderReconciliationMistakeList.stream().map(orderReconciliationMistake -> {
            if (StringUtils.isNoneBlank(orderReconciliationMistake.getOrdNo())) {
                return orderReconciliationMistake.getOrdNo();
            }
            return orderReconciliationMistake.getWxOrdNo();
        }).collect(Collectors.toList());
        //2、根据订单号查询已存在的OrderReconciliationMistake
        List<OrderReconciliationMistake> existOrderReconciliationMistakeList = orderReconciliationMistakeService.lambdaQuery()
                .eq(OrderReconciliationMistake::getIsDel, IsDelDbConstant.Y)
                .and(orderReconciliationMistakeLambdaQueryWrapper ->
                        orderReconciliationMistakeLambdaQueryWrapper.in(OrderReconciliationMistake::getOrdNo, ordNoList)
                                .or()
                                .in(OrderReconciliationMistake::getWxOrdNo, ordNoList)
                ).list();
        if (CollectionUtils.isEmpty(existOrderReconciliationMistakeList)) {
            //3、已存在的OrderReconciliationMistake为空
            orderReconciliationMistakeService.saveBatch(orderReconciliationMistakeList);
            return;
        }
        //4、删除已存在的OrderReconciliationMistake
        //4.1 数据库已存在的订单号
        List<String> existOrdNoList = existOrderReconciliationMistakeList.stream().map(orderReconciliationMistake -> {
            if (StringUtils.isNoneBlank(orderReconciliationMistake.getOrdNo())) {
                return orderReconciliationMistake.getOrdNo();
            }
            return orderReconciliationMistake.getWxOrdNo();
        }).distinct().collect(Collectors.toList());
        //4.2 根据订单号删除已存在的OrderReconciliationMistake
        orderReconciliationMistakeList.removeIf(orderReconciliationMistake -> existOrdNoList.stream().anyMatch(exsitOrdNo ->
                exsitOrdNo.equals(orderReconciliationMistake.getOrdNo()) || exsitOrdNo.equals(orderReconciliationMistake.getWxOrdNo())
        ));
        if(CollectionUtils.isEmpty(orderReconciliationMistakeList)){
            return;
        }
        //飞书提醒
//        fsMessageService.sendTextMessage(FSConstant.TextContentEnum.ORDER_RECONCILIATION_ADD_REPORT,GsonUtils.toJsonString(orderReconciliationMistakeList));
        orderReconciliationMistakeService.saveBatch(orderReconciliationMistakeList);
    }

    /**
     * 获取微信订单差集
     * 微信订单差集=昨日微信账单-昨日数据库账单
     *
     * @methodName: compareWxBillInfoListAndOrderInfo
     * @param wxBillInfoList
     * @param orderInfoList
     * @return: java.util.List<com.github.binarywang.wxpay.bean.result.WxPayBillInfo>
     * @author: ybw
     * @date: 2022/4/7
     **/
    private List<OrderReconciliationMistake> compareWxBillInfoListAndOrderInfo(List<WxPayBillInfo> wxBillInfoList, List<OrderInfo> orderInfoList) {
        if (CollectionUtils.isEmpty(wxBillInfoList)) {
            //1、昨日微信账单为空
            return new ArrayList<>();
        }
        if (CollectionUtils.isEmpty(orderInfoList)) {
            //2、昨日数据库账单为空
            return buildOrderReconciliationMistakeList(wxBillInfoList,OrderReconciliationMistakeDBConstant.Type.LOST_LIST);
        }
        //3、微信差集=昨日微信账单-昨日数据库账单
        List<WxPayBillInfo> diffWxBillInfoList = wxBillInfoList.stream().filter(wxPayBillInfo -> {
            return !orderInfoList.stream().anyMatch(orderInfo -> {
                //订单号相同且金额相同
                return orderInfo.getOrderNo().equals(wxPayBillInfo.getOutTradeNo()) && orderInfo.getPayPrice().equals(new BigDecimal(wxPayBillInfo.getTotalFee()));
            });
        }).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(diffWxBillInfoList)) {
            return new ArrayList<>();
        }
        //4、获取差异订单号
        List<String> ordNoList = diffWxBillInfoList.stream().map(WxPayBillInfo::getOutTradeNo).collect(Collectors.toList());
        List<OrderInfo> orderInfoList1 = this.lambdaQuery()
                .in(OrderInfo::getOrderNo, ordNoList)
                .list();
        if (CollectionUtils.isEmpty(orderInfoList1)) {
            return buildOrderReconciliationMistakeList(diffWxBillInfoList,OrderReconciliationMistakeDBConstant.Type.LOST_LIST);
        }
        //5、微信差异订单和所有数据库账单比较，数据库不存在数据
        return diffWxBillInfoList.stream().map(wxPayBillInfo -> {
            boolean flag=orderInfoList.stream().anyMatch(orderInfo ->
                    wxPayBillInfo.getOutTradeNo().equals(orderInfo.getOrderNo()));
            if(!flag){
                //5.1 订单不存在
                return buildOrderReconciliationMistake(wxPayBillInfo,OrderReconciliationMistakeDBConstant.Type.LOST_LIST);
            }
            flag=orderInfoList.stream().anyMatch(orderInfo ->
                    orderInfo.getPayPrice().equals(new BigDecimal(wxPayBillInfo.getTotalFee())));
            if(!flag){
                //5.2 金额不一致
                return buildOrderReconciliationMistake(wxPayBillInfo, OrderReconciliationMistakeDBConstant.Type.MONEY_DIFFER);
            }
            return null;
        }).filter(orderReconciliationMistake -> orderReconciliationMistake!=null).collect(Collectors.toList());
    }

    /**
     *
     * @methodName: buildOrderReconciliationMistake
     * @param wxPayBillInfoList
     * @return: java.util.List<com.zt.ztsc.server.modules.order.entity.OrderReconciliationMistake>
     * @author: ybw
     * @date: 2022/4/19
     **/
    private List<OrderReconciliationMistake> buildOrderReconciliationMistakeList(List<WxPayBillInfo> wxPayBillInfoList, OrderReconciliationMistakeDBConstant.Type type) {
        if (CollectionUtils.isEmpty(wxPayBillInfoList)) {
            return new ArrayList<>();
        }
        return wxPayBillInfoList.stream().map(wxPayBillInfo -> buildOrderReconciliationMistake(wxPayBillInfo,type)).collect(Collectors.toList());
    }

    /**
     *
     * @methodName: buildOrderReconciliationMistake
     * @param wxPayBillInfo
     * @param type
     * @return: com.zt.ztsc.server.modules.order.entity.OrderReconciliationMistake
     * @author: ybw
     * @date: 2022/4/19
     **/
    private OrderReconciliationMistake buildOrderReconciliationMistake(WxPayBillInfo wxPayBillInfo,OrderReconciliationMistakeDBConstant.Type type) {
        OrderReconciliationMistake orderReconciliationMistake = new OrderReconciliationMistake();
        orderReconciliationMistake.setType(type.getCode());
        orderReconciliationMistake.setWxOrdNo(wxPayBillInfo.getOutTradeNo());
        orderReconciliationMistake.setWxOrdStatus(OrderInfoDBConstant.Status.SUCCESS.getCode());
        orderReconciliationMistake.setWxOrdTotalMoneyPaid(new BigDecimal(wxPayBillInfo.getTotalFee()));
        orderReconciliationMistake.setStatus(OrderReconciliationMistakeDBConstant.Status.NOT_HANDLE);
        return orderReconciliationMistake;
    }

    /**
     * 获取数据库昨日账单
     *
     * @methodName: getYesterdaySuccessOrderInfo
     * @return: java.util.List<com.zt.ztsc.server.modules.order.entity.OrderInfo>
     * @author: ybw
     * @date: 2022/4/7
     *
     * @param yesterdayTime*/
    private List<OrderInfo> getYesterdaySuccessOrderInfo(LocalDateTime yesterdayTime) {
        //1、获取昨天的开始时间，结束时间
        LocalDateTime start = LocalDateTime.of(yesterdayTime.toLocalDate(), LocalTime.MIN);
        LocalDateTime end = LocalDateTime.of(yesterdayTime.toLocalDate(), LocalTime.MAX);
        //2、获取昨天的支付成功的订单
        return this.lambdaQuery()
                .ge(OrderInfo::getCreateTime,start)
                .le(OrderInfo::getCreateTime,end)
                .eq(OrderInfo::getStatus,OrderInfoDBConstant.Status.SUCCESS.getCode())
                .list();
    }

    /**
     * 获取昨日微信账单
     *
     * @methodName: getYesterdaySuccessBillInfoList
     * @return: java.util.List<com.github.binarywang.wxpay.bean.result.WxPayBillInfo>
     * @author: ybw
     * @date: 2022/4/7
     *
     * @param yesterdayTime*/
    private List<WxPayBillInfo> getYesterdaySuccessBillInfoList(LocalDateTime yesterdayTime) throws Exception {
        //1、获取昨日日期
        String yesterdayDate = DateTimeUtils.format(yesterdayTime.toLocalDate(),DateTimeUtils.yyyyMMdd);
        //2、获取微信昨日账单
        WxPayBillResult wxPayBillResult = downloadBill(yesterdayDate, WxPayConstants.BillType.SUCCESS);
        if(wxPayBillResult==null){
            return new ArrayList<>();
        }
        //3、筛选中体数藏-订单
        List<WxPayBillInfo> wxPayBillInfoList=wxPayBillResult.getBillInfoList();
        if(CollectionUtils.isEmpty(wxPayBillInfoList)){
            return new ArrayList<>();
        }
        return wxPayBillInfoList.stream().filter(wxPayBillInfo ->
                wxPayBillInfo.getOutTradeNo().startsWith(getOrderNoPre())
        ).collect(Collectors.toList());
    }

    /**
     * 微信-下载对账单
     *
     * @methodName: downloadBill
     * @param billDate
     * @param billType
     * @return: com.github.binarywang.wxpay.bean.result.WxPayBillResult
     * @author: ybw
     * @date: 2022/4/7
     **/
    public WxPayBillResult downloadBill(String billDate, String billType) throws Exception {
        WxPayDownloadBillRequest wxPayDownloadBillRequest=new WxPayDownloadBillRequest();
        wxPayDownloadBillRequest.setBillDate(billDate);
        wxPayDownloadBillRequest.setBillType(billType);
        WxPayBillResult wxPayBillResult= null;
        try {
            wxPayBillResult = wxPayConfiguration.getMaService(wxPayConfiguration.getDefaultAppid()).downloadBill(wxPayDownloadBillRequest);
            log.info("wxPayBillResult:{}", GsonUtils.toJsonString(wxPayBillResult));
        } catch (WxPayException e) {
            log.info("OrderInfoServiceImpl downloadBill error:",e);
        }
        return wxPayBillResult;
    }
}
